Fix lowering ARM shift by zero as a move. ARM does not support shifting by 0. An immediate value of 0 is interpreted as shifting by 32. See section A8.4.1 Constant shifts of the ARMv7-A/R reference manual. Change-Id: I289a7c6091c04387700dc2e9b3f959639bd919ce Reviewed-on: https://chromium-review.googlesource.com/491949 Reviewed-by: Jim Stichnoth <stichnot@chromium.org> 
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp index 6cc225c..3271271 100644 --- a/src/IceTargetLoweringARM32.cpp +++ b/src/IceTargetLoweringARM32.cpp 
@@ -2513,6 +2513,13 @@  return legalizeToReg(Target, Swapped ? Src0 : Src1);  }   + bool isSrc1ImmediateZero() const { + if (!swappedOperands() && hasConstOperand()) { + return getConstantValue() == 0; + } + return false; + } +  bool immediateIsFlexEncodable() const {  uint32_t Rotate, Imm8;  return OperandARM32FlexImm::canHoldImm(getConstantValue(), &Rotate, &Imm8); @@ -3422,8 +3429,12 @@  case InstArithmetic::Shl: {  Variable *Src0R = Srcs.unswappedSrc0R(this);  if (!isVectorType(T->getType())) { - Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); - _lsl(T, Src0R, Src1R); + if (Srcs.isSrc1ImmediateZero()) { + _mov(T, Src0R); + } else { + Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); + _lsl(T, Src0R, Src1R); + }  } else {  auto *Src1R = Srcs.unswappedSrc1R(this);  _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned); @@ -3434,11 +3445,15 @@  case InstArithmetic::Lshr: {  Variable *Src0R = Srcs.unswappedSrc0R(this);  if (!isVectorType(T->getType())) { - Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);  if (DestTy != IceType_i32) {  _uxt(Src0R, Src0R);  } - _lsr(T, Src0R, Src1R); + if (Srcs.isSrc1ImmediateZero()) { + _mov(T, Src0R); + } else { + Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); + _lsr(T, Src0R, Src1R); + }  } else {  auto *Src1R = Srcs.unswappedSrc1R(this);  auto *Src1RNeg = makeReg(Src1R->getType()); @@ -3454,7 +3469,11 @@  if (DestTy != IceType_i32) {  _sxt(Src0R, Src0R);  } - _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); + if (Srcs.isSrc1ImmediateZero()) { + _mov(T, Src0R); + } else { + _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); + }  } else {  auto *Src1R = Srcs.unswappedSrc1R(this);  auto *Src1RNeg = makeReg(Src1R->getType());